#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2008 ZHENG Zhong <heavyzheng nospam-at gmail D0T com>
# - http://heavyz.blogspot.com/
# - http://buggarden.blogspot.com/
#
# Views for the AFCP webapp.
#
# Created on 2008-10-28.
# $Id: views.py 300 2008-12-15 14:56:43Z heavyzheng $
#

import logging
import datetime
import random
import urllib

from django.template import loader
from django.template import Context
from django.http import HttpRequest
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from django.http import HttpResponseNotFound
from django.http import Http404

from google.appengine.api import memcache

from afcpweb.apps.afcp import utils
from afcpweb.apps.afcp import resources
from afcpweb.apps.afcp import paristech
from afcpweb.apps.afcp import planet
from afcpweb.apps.afcp import newsFeed
from afcpweb.apps.afcp.mail import send_mail

from afcpweb.apps.afcp.config import Config
from afcpweb.apps.afcp.models import MODELS_REVISION
from afcpweb.apps.afcp.models import AFCPUserProfile
from afcpweb.apps.afcp.models import AFCPAnnouncement
from afcpweb.apps.afcp.models import AFCPInscriptor
from afcpweb.apps.afcp.models import AFCPActivity

from afcpweb.apps.afcp.models import get_on_inscription_activity
from afcpweb.apps.afcp.models import set_on_inscription_activity
from afcpweb.apps.afcp.models import AFCPUser
from afcpweb.apps.afcp.models import get_current_user
from afcpweb.apps.afcp.models import create_login_url
from afcpweb.apps.afcp.models import create_logout_url
from google.appengine.ext import db

#---------------------------------------------------------------------------------------------------
# Language class
#---------------------------------------------------------------------------------------------------

class Language(object):
    
    LANG_SESSION_NAME = "django_language"
    
    ENGLISH_CODE = "en"
    FRENCH_CODE  = "fr"
    CHINESE_CODE = "zh-cn"
    
    DEFAULT_LANG_CODE    = FRENCH_CODE
    SUPPORTED_LANG_CODES = (  FRENCH_CODE, CHINESE_CODE, )
    
    
    def __init__(self, code, url, is_current):
        self.code = code
        self.url = url
        self.is_current = is_current
    
    @staticmethod
    def create_lang_url(redirect_url, lang_code):
        params = { "url" : redirect_url, "lang" : lang_code, }
        url = "%s/lang/?%s" % (Config.URL_PREFIX, urllib.urlencode(params))
        return url
    
    @staticmethod
    def get_lang(request):
        try:
            lang_code = request.session.get(Language.LANG_SESSION_NAME, None)
        except AttributeError:
            lang_code = Language.DEFAULT_LANG_CODE
        return lang_code
    
    @staticmethod
    def set_lang(request, lang_code):
        try:
            request.session[Language.LANG_SESSION_NAME] = lang_code
            return True
        except AttributeError:
            return False


#---------------------------------------------------------------------------------------------------
# Common functions
#---------------------------------------------------------------------------------------------------

def _get_common_context_dict(request):

    # User info.
    user = get_current_user()
    if not user:
        log_url  = create_login_url("%s/login_ok/%s" % (Config.URL_PREFIX, request.path,))
        log_text = "Login"
        is_admin = False
    else:
        log_url  = create_logout_url("%s/login_ok/%s" % (Config.URL_PREFIX, request.path,))
        log_text = "Logout"
        is_admin = (user.email() in Config.ADMINS)
    
    # Language.
    current_lang_code = Language.get_lang(request)
    languages = []
    for lang_code in Language.SUPPORTED_LANG_CODES:
        lang_url    = Language.create_lang_url(request.path, lang_code)
        is_current  = (lang_code == current_lang_code)
        languages.append(Language(lang_code, lang_url, is_current))
    
    # Request meta info.
    http_referer = request.META.get("HTTP_REFERER", "unknown_http_referer")
    remote_addr  = request.META.get("REMOTE_ADDR" , "unknown_remote_addr" )
    remote_host  = request.META.get("REMOTE_HOST" , "unknown_remote_host" )
    
    # Return the common context dict.
    return { "user_"            : user,
             "log_url_"         : log_url,
             "log_text_"        : log_text,
             "is_admin_"        : is_admin,
             "url_"             : Config.URL_PREFIX,
             "static_"          : Config.STATIC_PREFIX,
             "languages_"       : languages,
             "http_referer_"    : http_referer,
             "remote_addr_"     : remote_addr,
             "remote_host_"     : remote_host,
             "models_revision_" : MODELS_REVISION, }

def _redirect_to_error_page(error):
    params = { "error" : error, }
    url = "%s/error/?%s" % (Config.URL_PREFIX, urllib.urlencode(params))
    return HttpResponseRedirect(url)


#---------------------------------------------------------------------------------------------------
# Change current language and logged-in/logged-out redirect
#---------------------------------------------------------------------------------------------------

def change_language(request):
    "Change the current language."
    
    redirect_url = utils.get_param(request.REQUEST, "url" )
    lang_code    = utils.get_param(request.REQUEST, "lang")
    Language.set_lang(request, lang_code)
    return HttpResponseRedirect(redirect_url)


def login_ok(request, url):
    try:
        profile = get_current_user().profile()
        if profile:
            profile.count_login()
            profile.put()
    except:
        pass
    return HttpResponseRedirect(url)


def logout_ok(request, url):
    return HttpResponseRedirect(url)


#---------------------------------------------------------------------------------------------------
# Home page, 404 not-found page, error page and static pages
#---------------------------------------------------------------------------------------------------

def home(request):
    "Displays the AFCP home page."
    
    announcements = AFCPAnnouncement.gql("ORDER BY post_date DESC").fetch(5, 0)
    ctxt_dict = { "announcements" : announcements,
                  "ecoles"        : paristech.ECOLES.values(),
                  "universities"  : paristech.UNIVERSITIES.values(),
                  "feeds"         : newsFeed.FEEDS,
                  "banner_image"  : random.choice(resources.BANNER_IMAGES), }
    ctxt_dict.update(_get_common_context_dict(request))
    ctxt = Context(ctxt_dict)
    tmpl = loader.get_template("%s/home.html" % Config.APP_NAME)
    return HttpResponse(tmpl.render(ctxt))


def not_found(request):
    "Displays the 404 not-found page."
    
    ctxt_dict = { "url" : request.path, }
    ctxt_dict.update(_get_common_context_dict(request))
    ctxt = Context(ctxt_dict)
    tmpl = loader.get_template("%s/not_found.html" % Config.APP_NAME)
    return HttpResponseNotFound(tmpl.render(ctxt))


def error_page(request):
    "Displays the error page."
    
    ctxt_dict = { "error" : utils.get_param(request.REQUEST, "error"), }
    ctxt_dict.update(_get_common_context_dict(request))
    ctxt = Context(ctxt_dict)
    tmpl = loader.get_template("%s/error.html" % Config.APP_NAME)
    return HttpResponse(tmpl.render(ctxt))

#---------------------------------------------------------------------------------------------------
# url function
#---------------------------------------------------------------------------------------------------

def contact(request, lang=None):
	"Displays the requested static contact page in a requested or the current language."
	
	if lang is None:
		lang = Language.SUPPORTED_LANG_CODES
	if lang not in Language.SUPPORTED_LANG_CODES:
		lang = Language.DEFAULT_LANG_CODE
	
	ctxt_dict = { "page_name" : "contact",
				  "lang_code" :lang,}
				
	ctxt_dict.update(_get_common_context_dict(request))
	ctxt = Context(ctxt_dict)
	tmpl = loader.get_template("%s/static/%s/contact/contact.html" % (Config.APP_NAME, lang ) )
	return HttpResponse(tmpl.render(ctxt))
#---------------------------------------------------------------------------------------------------	
def about(request, name=None, lang=None):
    "Displays the requested static about page in a requested or the current language."
    supage = "about"
    STATIC_PAGES = ( "nous", "paristech ", "paristechchine" , "bureau")
    
	
    if name is None:
        name = "nous"
	if name not in STATIC_PAGES:
		not_found(request)
    
		
    if lang is None:
        lang = Language.get_lang(request)
    if lang not in Language.SUPPORTED_LANG_CODES:
        lang = Language.DEFAULT_LANG_CODE
		
    ctxt_dict = { "page_name"    : name,
                  "lang_code"    : lang, }
    ctxt_dict.update(_get_common_context_dict(request))
    ctxt = Context(ctxt_dict)
    tmpl = loader.get_template("%s/static/%s/%s/%s.html" % (Config.APP_NAME, lang, supage, name ))
    return HttpResponse(tmpl.render(ctxt))


#---------------------------------------------------------------------------------------------------

def news(request):
    "Displays the planet AFCP page (a feeds aggregator)."
    
    ctxt_dict = { "feeds" 	  : newsFeed.FEEDS,
				  "page_name" : "news",
				  }
    ctxt_dict.update(_get_common_context_dict(request))
    ctxt = Context(ctxt_dict)
    tmpl = loader.get_template("%s/news.html" % Config.APP_NAME)
    return HttpResponse(tmpl.render(ctxt))

#---------------------------------------------------------------------------------------------------
def members(request):
    """Displays the AFCP members list."""
    
    MEMBERS_PER_PAGE = 10
    query = AFCPUserProfile.gql("WHERE deleted=:deleted ORDER BY name", deleted=False)
    page_number = utils.get_param(request.REQUEST, "page")
    members = utils.EntityPage(query, MEMBERS_PER_PAGE, page_number)
   
    ctxt_dict = { "members" : members, 
				  "has_previous" : members.has_previous(),
				  "has_next"	: members.has_next(), 
				  "previous_page" : members.previous_page_number(),
				  "next_page"	: members.next_page_number(),}
				  
    ctxt_dict.update(_get_common_context_dict(request))
    ctxt = Context(ctxt_dict)
    tmpl = loader.get_template("%s/members.html" % Config.APP_NAME)
    return HttpResponse(tmpl.render(ctxt))
		
def profile(request, uid):
    """Displays the member profile by UID."""
    
    profile = AFCPUserProfile.gql("WHERE uid=:uid", uid=uid).get()
    if profile is None:
        return not_found(request)
    
    if request.method == "GET":
        ctxt_dict = { "info"         : utils.get_param(request.GET, "info"),
                      "error"        : utils.get_param(request.GET, "error"),
                      "uid"          : uid,
                      "profile"      : profile,
                      "ecoles"       : paristech.ECOLES.values(),
                      "universities" : paristech.UNIVERSITIES.values(), }
        ctxt_dict.update(_get_common_context_dict(request))
        ctxt = Context(ctxt_dict)
        tmpl = loader.get_template("%s/profile.html" % Config.APP_NAME)
        return HttpResponse(tmpl.render(ctxt))
    
    elif request.method == "POST":
    
        params = {}
        action = utils.get_param(request.POST, "action")
        try:
            if action == "edit":
                
                # Update basic information.
                profile.name = utils.get_param(request.POST, "name")
                profile.name_zh = utils.get_param(request.POST, "name_zh")
                profile.sex = utils.get_param(request.POST, "sex")
                birthday_str = utils.get_param(request.POST, "birthday")
                if birthday_str is not None:
                    profile.birthday = datetime.datetime.strptime(birthday_str, "%Y-%m-%d")
                else:
                    profile.birthday = None
                promo_str = utils.get_param(request.POST, "promo")
                if promo_str is not None:
                    profile.promo = int(promo_str)
                else:
                    profile.promo = None
                profile.ecole_id = utils.get_param(request.POST, "ecole_id")
                profile.univ_id = utils.get_param(request.POST, "univ_id")
                profile.alt_email = utils.get_param(request.POST, "alt_email")
                profile.tel = utils.get_param(request.POST, "tel")
                
                # Update profile photo.
                query_dict = request.POST.copy()
                query_dict.update(request.FILES)
                photo_dict = query_dict.get("photo", None)
                if photo_dict is not None:
                    profile.photo_type = utils.get_param(photo_dict, "content-type")
                    profile.photo_data = photo_dict.get("content")
                elif utils.get_param(request.POST, "delete_photo") == "1":
                    profile.photo_type = None
                    profile.photo_data = None
                
                # Update profile in datastore.
                profile.put()
                params["info"] = "Profile updated successfully."
            
            elif action == "delete":
                profile.deleted = True
                profile.put()
                params["info"] = "Profile deleted successfully."
            
            elif action == "restore":
                profile.deleted = False
                profile.put()
                params["info"] = "Profile restored successfully."
            
            else:
                raise Exception, "Unknown action '%s'." % action
        
        except Exception, ex:
            error = "Failed to perform action '%s': %s" % (action, str(ex))
            logging.error(error)
            params["error"] = error
        
        return HttpResponseRedirect("%s?%s" % (request.path, urllib.urlencode(params)))


def profile_photo(request, uid):
    
    profile = AFCPUserProfile.gql("WHERE uid=:uid", uid=uid).get()
    if profile is None:
        return not_found(request)
    
    if request.method == "GET":
        if profile.has_photo():
            return HttpResponse(profile.photo_data, mimetype=profile.photo_type)
        else:
            return not_found(request)


def my_profile(request):
    """If current user already has a profile, redirect to the profile page; otherwise, display the
    create profile page.
    """
    
    # Anonymous user should not have arrived to this page.
    user = get_current_user()
    if not user:
        return HttpResponseRedirect("%s/" % Config.URL_PREFIX)
    
    # If the user already has a profile, redirect to the profile page.
    if user.profile() is not None:
        return HttpResponseRedirect("%s/profile/%s/" % (Config.URL_PREFIX, user.profile().uid))
    
    # Create profile for the current user.
    if request.method == "GET":
        # Return the create profile form.
        ctxt_dict = { "error"        : utils.get_param(request.GET, "error"),
                      "ecoles"       : paristech.ECOLES.values(),
                      "universities" : paristech.UNIVERSITIES.values(), }
        ctxt_dict.update(_get_common_context_dict(request))
        ctxt = Context(ctxt_dict)
        tmpl = loader.get_template("%s/create_profile.html" % Config.APP_NAME)
        return HttpResponse(tmpl.render(ctxt))
    
    elif request.method == "POST":
        # Create a profile for the current user.
        try:
            profile = AFCPUserProfile( key_name=user.email(),
                                       uid=utils.generate_random_id("U"),
                                       name=utils.get_param(request.POST, "name"),
                                       name_zh=utils.get_param(request.POST, "name_zh"),
                                       status=AFCPUserProfile.PENDING_STATUS )
            profile.put()
            return HttpResponseRedirect("%s/profile/%s/" % (Config.URL_PREFIX, profile.uid))
        except Exception, ex:
            error = "Failed to create user profile: %s" % str(ex)
            logging.error(error)
            params = { "error" : error, }
            return HttpResponseRedirect("%s?%s" % (request.path, urllib.urlencode(params)))


def random_profile(request):
    # TODO: count() and fetch() cannot handle a large amount of results.
    # This function should be redesigned to be more scalable.
    query = AFCPUserProfile.gql("")
    count = query.count()
    if count <= 0:
        return not_found(request)
    
    random_offset = random.choice(range(0, count))
    profile_list  = query.fetch(1, random_offset)
    if not profile_list:
        return not_found(request)
    else:
        profile_uid = profile_list[0].uid
        return HttpResponseRedirect("%s/profile/%s/" % (Config.URL_PREFIX, profile_uid))

#---------------------------------------------------------------------------------------------------
def ecole(request, acronym):

    if request.method == "GET":
        MEMBERS_PER_PAGE = 20
        query = AFCPUserProfile.gql( "WHERE ecole_id=:acronym AND deleted=:deleted ORDER BY name",
                                     acronym=acronym,
                                     deleted=False )
        page_number = utils.get_param(request.REQUEST, "page")
        members = utils.EntityPage(query, MEMBERS_PER_PAGE, page_number)
        ctxt_dict = { "members" : members,
                      "ecole"   : paristech.ECOLES.get(acronym),
                      "ecoles"  : paristech.ECOLES.values(), }
        ctxt_dict.update(_get_common_context_dict(request))
        ctxt = Context(ctxt_dict)
        tmpl = loader.get_template("%s/ecole.html" % Config.APP_NAME)
        return HttpResponse(tmpl.render(ctxt))


def university(request, acronym):

    if request.method == "GET":
        MEMBERS_PER_PAGE = 20
        query = AFCPUserProfile.gql( "WHERE univ_id=:acronym AND deleted=:deleted ORDER BY name",
                                     acronym=acronym,
                                     deleted=False )
        page_number = utils.get_param(request.REQUEST, "page")
        members = utils.EntityPage(query, MEMBERS_PER_PAGE, page_number)
        ctxt_dict = { "members"      : members,
                      "university"   : paristech.UNIVERSITIES.get(acronym),
                      "universities" : paristech.UNIVERSITIES.values(), }
        ctxt_dict.update(_get_common_context_dict(request))
        ctxt = Context(ctxt_dict)
        tmpl = loader.get_template("%s/university.html" % Config.APP_NAME)
        return HttpResponse(tmpl.render(ctxt))

def amusement(request, name=None):
    "Displays the requested amusement page in a requested or the current language."
    
    STATIC_PAGES = ( "planet",)
    
	
    if name is None:
        name = "planet"
	
	
	if name is "planet":
		return planet_afcp(request)
	
	return not_found(request)

def planet_afcp(request):
    "Displays the planet AFCP page (a feeds aggregator)."
    
	
    ctxt_dict = { "feeds" 	  : planet.FEEDS,
				  "page_name" : "planet",
				  }
    ctxt_dict.update(_get_common_context_dict(request))
    ctxt = Context(ctxt_dict)
    tmpl = loader.get_template("%s/amusement/planet.html" % Config.APP_NAME)
    return HttpResponse(tmpl.render(ctxt))

#---------------------------------------------------------------------------------------------------
	
def create_inscription(request, uid = None):
	"""Create the inscriptor."""
	
	inscriptor = AFCPInscriptor.gql("WHERE uid=:uid", uid=uid).get()
	#inscriptors_plus_activity = AFCPInscriptor.gql("WHERE present_plus_activity=:present_plus_activity", present_plus_activity="yes")
	query = AFCPInscriptor.gql("WHERE present_plus_activity=:present_plus_activity", present_plus_activity="yes")
	page_number = utils.get_param(request.REQUEST, "page")
	inscriptors_plus_activity = utils.EntityPage( query, 5, page_number )
	
	has_place = True
	
	if inscriptors_plus_activity.object_count > 35 :
		has_place = False
	
	
	
	if request.method == "GET":
		if inscriptor is None:
			isUpdateMode = False
		else :	
			isUpdateMode = True
		activity = get_on_inscription_activity()
		# enter the information
		ctxt_dict = { "isUpdateMode"  : isUpdateMode,
					  "info"          : utils.get_param(request.GET, "info"),
					  "error"         : utils.get_param(request.GET, "error"),
					  "activity"	  : activity,
					  "inscriptor"	  : inscriptor,
					  "has_place"	  : has_place,
					  "inscriptors_plus_activity"	  : inscriptors_plus_activity,
					  "ecoles"        : paristech.ECOLES.values(),
					  "universities"  : paristech.UNIVERSITIES.values(),}
					  
		ctxt_dict.update(_get_common_context_dict(request))
		ctxt = Context(ctxt_dict)
		tmpl = loader.get_template("%s/inscription/create_inscription.html" % Config.APP_NAME)
		return HttpResponse(tmpl.render(ctxt))
	elif request.method == "POST":
		# Create a inscriptor for the current user.
		try:
			univ_id = utils.get_param(request.POST, "univ_id")
			if univ_id == "None":
				univ_id = utils.get_param(request.POST, "univ_id_back")
			
			ecole_id = utils.get_param(request.POST, "ecole_id")
			if ecole_id == "None":
				ecole_id = utils.get_param(request.POST, "ecole_id_back")
			
			if uid is None:					
				inscriptor = AFCPInscriptor(uid=utils.generate_random_id("U"),
											first_name=utils.get_param(request.POST, "first_name"),
											last_name=utils.get_param(request.POST, "last_name"),
											name_zh=utils.get_param(request.POST, "name_zh"),
											sex = utils.get_param(request.POST, "sex"),
											ecole_id = ecole_id,
											univ_id = univ_id,
											alt_email = utils.get_param(request.POST, "alt_email"),
											present_plus_activity = utils.get_param(request.POST,"present_plus_activity"),
											activity = get_on_inscription_activity() )	
			
			else:
				inscriptor = AFCPInscriptor.gql("WHERE uid=:uid", uid=uid).get()
				first_name=utils.get_param(request.POST, "first_name"),
				last_name=utils.get_param(request.POST, "last_name"),
				inscriptor.name_zh=utils.get_param(request.POST, "name_zh")
				inscriptor.sex = utils.get_param(request.POST, "sex")
				inscriptor.ecole_id = ecole_id
				inscriptor.univ_id = univ_id
				inscriptor.alt_email = utils.get_param(request.POST, "alt_email")
				inscriptor.present_plus_activity = utils.get_param(request.POST,"present_plus_activity")
				inscriptor.activity = get_on_inscription_activity()
				
			inscriptor.put()
					# enter the information
			activity = get_on_inscription_activity()	
			

		
			ctxt_dict = { 
						  "info"          : utils.get_param(request.GET, "info"),
						  "error"         : utils.get_param(request.GET, "error"),
						  "activity"	  : activity,
						  "inscriptor"	  : inscriptor,
						  "has_place"	  : has_place,
						  "inscriptors_plus_activity"	  : inscriptors_plus_activity,
						  "ecoles"        : paristech.ECOLES.values(),
						  "universities"  : paristech.UNIVERSITIES.values(),}
					  
			ctxt_dict.update(_get_common_context_dict(request))
			ctxt = Context(ctxt_dict)
			tmpl = loader.get_template("%s/inscription/show_inscription.html" % Config.APP_NAME)
			return HttpResponse(tmpl.render(ctxt))
		except Exception, ex:
			error = "Failed to create user inscriptor: %s" % str(ex)
			logging.error(error)
			params = { "error" : error, }
			return HttpResponseRedirect("%s?%s" % (request.path, urllib.urlencode(params)))

def cancel_inscription(request, uid):

	inscriptor = AFCPInscriptor.gql("WHERE uid=:uid", uid=uid).get()
	if inscriptor is None:
		error = "Failed to cancel inscriptor." 
		logging.error(error)
		params = { "error" : error, }
		return HttpResponseRedirect("/afcp/inscription/create/?%s" % urllib.urlencode(params) )
	else:
		inscriptor.delete()
		info = "Success to cancel inscriptor, you will receive our email for confimation." 
		logging.info(info)
		params = { "info" : info, }
		return HttpResponseRedirect("/afcp/inscription/create/?%s" % urllib.urlencode(params) )	
	
#---------------------------------------------------------------------------------------------------
# admin page 
#---------------------------------------------------------------------------------------------------

def admin(request):
	return admin_inscription(request)
	
def admin_membre(request):
    "Displays the admin console and handles the admin request."
    
    user = get_current_user()
    if user.email() not in Config.ADMINS:
        return HttpResponseRedirect("%s/" % Config.URL_PREFIX)
    
    error = utils.get_param(request.GET, "error")
    info  = utils.get_param(request.GET, "info" )
        
    PROFILES_PER_PAGE = 10
    query = AFCPUserProfile.gql("")
    page_number = utils.get_param(request.REQUEST, "page")
    profiles = utils.EntityPage(query, PROFILES_PER_PAGE, page_number)
        
    ctxt_dict = { "info" : info, 
	              "error" : error, 
				  "profiles" : profiles, 
				  "has_previous" : profiles.has_previous(),
				  "has_next"	: profiles.has_next(), 
				  "previous_page" : profiles.previous_page_number(),
				  "next_page"	: profiles.next_page_number(), }
					 
    ctxt_dict.update(_get_common_context_dict(request))
    ctxt = Context(ctxt_dict)
    tmpl = loader.get_template("%s/admin/admin_membres.html" % Config.APP_NAME)
    return HttpResponse(tmpl.render(ctxt))
    
            

def admin_inscription(request):
    "Displays the admin console and handles the admin request."
    
    user = get_current_user()
    if user.email() not in Config.ADMINS:
        return HttpResponseRedirect("%s/" % Config.URL_PREFIX)
    
    if request.method == "GET":
    
		error = utils.get_param(request.GET, "error")
		info  = utils.get_param(request.GET, "info" )
        
		INSCRIPTOR_PER_PAGE = 12
		query = AFCPInscriptor.gql("")
		page_number = utils.get_param(request.REQUEST, "page")
		inscriptors = utils.EntityPage(query, INSCRIPTOR_PER_PAGE, page_number)
        
		
		activities = db.GqlQuery('SELECT * FROM AFCPActivity')
	
		ctxt_dict = { "info" : 			info, 
					  "error" : 		error, 
					  "inscriptors" :   inscriptors, 
					  "activities"	:	activities,
					  "has_previous" :  inscriptors.has_previous(),
					  "has_next"	:   inscriptors.has_next(), 
					  "previous_page" : inscriptors.previous_page_number(),
					  "next_page"	:   inscriptors.next_page_number(), }
					 
		ctxt_dict.update(_get_common_context_dict(request))
		ctxt = Context(ctxt_dict)
		tmpl = loader.get_template("%s/admin/admin_inscription.html" % Config.APP_NAME)
		return HttpResponse(tmpl.render(ctxt))
    
    elif request.method == "POST":
        error = None
        info  = None
        try:
			uid   = utils.get_param(request.POST, "activity_id")
			activity_chosed = AFCPActivity.gql("WHERE uid=:uid", uid=uid).get()
            
			if activity_chosed is None:
				raise Exception("Failed to find current activity  ")            

        except Exception, ex:
            error = "Failed to process admin action. %s" % ex 
            logging.error(error)
        
        params = { "activity_chosed_id" : activity_chosed.uid, }
        if error is not None:
            params["error"] = error
        if info is not None:
            params["info"] = info
        redirect_url = "%s/admin/inscription/?%s" % (Config.URL_PREFIX, urllib.urlencode(params))
        return HttpResponseRedirect(redirect_url)

#---------------------------------------------------------------------------------------------------

def admin_change_inscription(request, uid = None):
	"""Change the inscriptor."""
	inscriptor = AFCPInscriptor.gql("WHERE uid=:uid", uid=uid).get()
	if request.method == "GET":
		# enter the information page
		isUpdateMode = True
		ctxt_dict = { "isUpdateMode"  : isUpdateMode,
					  "info"          : utils.get_param(request.GET, "info"),
					  "error"         : utils.get_param(request.GET, "error"),
					  "inscriptor"	  : inscriptor,
					  "ecoles"        : paristech.ECOLES.values(),
					  "universities"  : paristech.UNIVERSITIES.values(),}
					  
		ctxt_dict.update(_get_common_context_dict(request))
		ctxt = Context(ctxt_dict)
		tmpl = loader.get_template("%s/admin/inscription/change_inscription.html" % Config.APP_NAME)
		return HttpResponse(tmpl.render(ctxt))
	elif request.method == "POST":
		# Create a inscriptor for the current user.
		try:
			univ_id = utils.get_param(request.POST, "univ_id")
			if univ_id == "None":
				univ_id = utils.get_param(request.POST, "univ_id_back")
			
			ecole_id = utils.get_param(request.POST, "ecole_id")
			if ecole_id == "None":
				ecole_id = utils.get_param(request.POST, "ecole_id_back")
				
			if uid is None:
				inscriptor = AFCPInscriptor(uid=utils.generate_random_id("U"),
											name=utils.get_param(request.POST, "name"),
											name_zh=utils.get_param(request.POST, "name_zh"),
											sex = utils.get_param(request.POST, "sex"),
											ecole_id = ecole_id,
											univ_id = univ_id,
											alt_email = utils.get_param(request.POST, "alt_email"),
											present_plus_activity = utils.get_param(request.POST,"present_plus_activity")
											)	
			else:
				inscriptor = AFCPInscriptor.gql("WHERE uid=:uid", uid=uid).get()
				inscriptor.name=utils.get_param(request.POST, "name")
				inscriptor.name_zh=utils.get_param(request.POST, "name_zh")
				inscriptor.sex = utils.get_param(request.POST, "sex")
				inscriptor.ecole_id = ecole_id
				inscriptor.univ_id = univ_id
				inscriptor.alt_email = utils.get_param(request.POST, "alt_email")
				inscriptor.present_plus_activity = utils.get_param(request.POST,"present_plus_activity")
			inscriptor.put()
					# enter the information
			ctxt_dict = { 
						  "info"          : utils.get_param(request.GET, "info"),
						  "error"         : utils.get_param(request.GET, "error"),
						  "inscriptor"	  : inscriptor,
						  "ecoles"        : paristech.ECOLES.values(),
						  "universities"  : paristech.UNIVERSITIES.values(),}
					  
			ctxt_dict.update(_get_common_context_dict(request))
			ctxt = Context(ctxt_dict)
			tmpl = loader.get_template("%s/admin/inscription/show_inscription.html" % Config.APP_NAME)
			return HttpResponse(tmpl.render(ctxt))
		except Exception, ex:
			error = "Failed to create user inscriptor: %s" % str(ex)
			logging.error(error)
			params = { "error" : error, }
			return HttpResponseRedirect("%s?%s" % (request.path, urllib.urlencode(params)))		
	
def admin_show_inscription(request, uid):
	"""Display the inscription information"""
	if uid is None :
		return not_found(request)
	else :
		inscriptor = AFCPInscriptor.gql("WHERE uid=:uid", uid=uid).get()	
		ctxt_dict = { 	"info"          : utils.get_param(request.GET, "info"),
						"error"         : utils.get_param(request.GET, "error"),
						"inscriptor"	  : inscriptor,
						"ecoles"        : paristech.ECOLES.values(),
						"universities"  : paristech.UNIVERSITIES.values(),}		
		ctxt_dict.update(_get_common_context_dict(request))
		ctxt = Context(ctxt_dict)
		tmpl = loader.get_template("%s/admin/inscription/show_inscription.html" % Config.APP_NAME)
		return HttpResponse(tmpl.render(ctxt))		

def admin_cancel_inscription(request, uid):
	"""Cancel the inscription information"""
	
	if request.method == "GET":
		inscriptor = AFCPInscriptor.gql("WHERE uid=:uid", uid=uid).get()
		activity = get_on_inscription_activity()
		# enter the information
		ctxt_dict = { "info"          : utils.get_param(request.GET, "info"),
					  "error"         : utils.get_param(request.GET, "error"),
					  "activity"	  : activity,
					  "inscriptor"	  : inscriptor,
					  "ecoles"        : paristech.ECOLES.values(),
					  "universities"  : paristech.UNIVERSITIES.values(),}
					  
		ctxt_dict.update(_get_common_context_dict(request))
		ctxt = Context(ctxt_dict)
		tmpl = loader.get_template("%s/admin/inscription/cancel_inscription.html" % Config.APP_NAME)
		return HttpResponse(tmpl.render(ctxt))
	
	elif request.method == "POST":
		uid = utils.get_param(request.POST, "uid")
		inscriptor = AFCPInscriptor.gql("WHERE uid=:uid", uid=uid).get()
		if inscriptor is None:
			error = "Failed to cancel inscriptor." 
			logging.error(error)
			params = { "error" : error, }
			return HttpResponseRedirect("/afcp/admin/inscription/create/?%s" % urllib.urlencode(params) )
		else:
			inscriptor.delete()
			info = "Success to cancel inscriptor." 
			logging.info(info)
			params = { "info" : info, }
			return HttpResponseRedirect("/afcp/admin/inscription/?%s" % urllib.urlencode(params) )	

def admin_confirm_inscriptor( request, uid ):

	inscriptor = AFCPInscriptor.gql("WHERE uid=:uid", uid=uid).get()
	if inscriptor is None:
		error = "Failed to confirm this inscriptor." 
		logging.error(error)
		params = { "error" : error,
				   "inscriptor" : inscriptor, }
		return HttpResponseRedirect("/afcp/admin/inscription/show/%s?%s" % (uid, urllib.urlencode(params) ) )	
	else:
		inscriptor.isConfirmed = "yes"
		inscriptor.put()
		
		info = "Success to confirm this inscriptor"
		logging.info(info)
		params = { "info" : info,
				   "inscriptor" : inscriptor, }
		return HttpResponseRedirect("/afcp/admin/inscription/show/%s?%s" % (uid, urllib.urlencode(params) ) )

def admin_confirm_email_inscriptor(request, uid ):

	inscriptor = AFCPInscriptor.gql("WHERE uid=:uid", uid=uid).get()
	if inscriptor is None:
		error = "Failed to confirm this inscriptor." 
		logging.error(error)
		params = { "error" : error,
				   "inscriptor" : inscriptor, }
		return HttpResponseRedirect("/afcp/admin/inscription/show/%s?%s" % (uid, urllib.urlencode(params) ) )	
	else:
		inscriptor.isConfirmed = "yes"
		info_email = send_mail( uid, inscriptor.alt_email )
		inscriptor.is_send_email = "yes"
		inscriptor.put()
		
		info = "Success to confirm this inscriptor. %s " % info_email
		logging.info(info)
		params = { "info" : info,
				   "inscriptor" : inscriptor, }
		return HttpResponseRedirect("/afcp/admin/inscription/show/%s?%s" % (uid, urllib.urlencode(params) ) )	

def admin_csv_output(request):
	
	#inscriptors = AFCPInscriptor.gql("")
	inscriptors = db.GqlQuery('SELECT * FROM AFCPInscriptor')
	filename = "afcp"
	response = HttpResponse(mimetype='text/csv')
	response['Content-Disposition'] = 'attachment; filename=%s.csv' % filename

	t = loader.get_template("%s/admin/inscription/csv.html" % Config.APP_NAME)
	c = Context({
		'inscriptors': inscriptors,
	})
	response.write(t.render(c))
	return response

	
def admin_activity(request):
    "Displays the admin console and handles the admin request."
    
    user = get_current_user()
    if user.email() not in Config.ADMINS:
        return HttpResponseRedirect("%s/" % Config.URL_PREFIX)
    
    error = utils.get_param(request.GET, "error")
    info  = utils.get_param(request.GET, "info" )
        
    ACTIVITY_PER_PAGE = 8
    query = AFCPActivity.gql("")
    page_number = utils.get_param(request.REQUEST, "page")
    activities = utils.EntityPage(query, ACTIVITY_PER_PAGE, page_number)
        
    ctxt_dict = { "info" : info, 
	              "error" : error, 
				  "activities" : activities, 
				  "has_previous" : activities.has_previous(),
				  "has_next"	: activities.has_next(), 
				  "previous_page" : activities.previous_page_number(),
				  "next_page"	: activities.next_page_number(), }
					 
    ctxt_dict.update(_get_common_context_dict(request))
    ctxt = Context(ctxt_dict)
    tmpl = loader.get_template("%s/admin/admin_activities.html" % Config.APP_NAME)
    return HttpResponse(tmpl.render(ctxt))


def admin_create_activity(request, uid = None):
	"""Create the activity."""
	
	activity = AFCPActivity.gql("WHERE uid=:uid", uid=uid).get()
	if request.method == "GET":
		if activity is None:
			isUpdateMode = False
		else :	
			isUpdateMode = True
		
		# enter the information
		ctxt_dict = { "isUpdateMode"  : isUpdateMode,
					  "info"          : utils.get_param(request.GET, "info"),
					  "error"         : utils.get_param(request.GET, "error"),
					  "activity"	  : activity,}
					  
		ctxt_dict.update(_get_common_context_dict(request))
		ctxt = Context(ctxt_dict)
		tmpl = loader.get_template("%s/admin/activity/create_activity.html" % Config.APP_NAME)
		return HttpResponse(tmpl.render(ctxt))
	elif request.method == "POST":
			# Create an activity for the current user.
		try:
			date_str =  utils.get_param(request.POST, "date")
			if date_str is not None:
					date = datetime.datetime.strptime(date_str, "%Y-%m-%d %H:%M")
			else:
				date = None
				
			if uid is None:				
				activity = AFCPActivity( uid=utils.generate_random_id("U") ,
										 name=utils.get_param(request.POST, "name"),
										 subject= utils.get_param(request.POST, "subject"),
										 address= utils.get_param(request.POST, "address"),
										 date= date,
										 isOnScription = "Non" )		
			else:
				activity = AFCPActivity.gql("WHERE uid=:uid", uid=uid).get()
				activity.name = utils.get_param(request.POST, "name")
				activity.subject = utils.get_param(request.POST, "subject")
				activity.address = address= utils.get_param(request.POST, "address")
				activity.date = date

			activity.put()
			
			ctxt_dict = { "info"          : utils.get_param(request.GET, "info"),
						  "error"         : utils.get_param(request.GET, "error"),
						  "activity"	  : activity,}
					  
			ctxt_dict.update(_get_common_context_dict(request))
			ctxt = Context(ctxt_dict)
			tmpl = loader.get_template("%s/admin/activity/show_activity.html" % Config.APP_NAME)
			return HttpResponse(tmpl.render(ctxt))
		except Exception, ex:
			error = "Failed to create an activity: %s" % str(ex)
			logging.error(error)
			params = { "error" : error,
					   "activity" : activity, }
			return HttpResponseRedirect("%s?%s" % (request.path, urllib.urlencode(params)))


		
def admin_show_activity(request,uid):

	activity = AFCPActivity.gql("WHERE uid=:uid", uid=uid).get()
	if request.method == "GET":
		
		ctxt_dict = { "info"          : utils.get_param(request.GET, "info"),
					  "error"         : utils.get_param(request.GET, "error"),
					  "activity"	  : activity,}
						  
		ctxt_dict.update(_get_common_context_dict(request))
		ctxt = Context(ctxt_dict)
		tmpl = loader.get_template("%s/admin/activity/show_activity.html" % Config.APP_NAME)
		return HttpResponse(tmpl.render(ctxt))
	else :
		return not_found(request)
			
def admin_cancel_activity(request, uid):

	activity = AFCPActivity.gql("WHERE uid=:uid", uid=uid).get()
	if activity is None:
		error = "Failed to cancel activity." 
		logging.error(error)
		params = { "error" : error, }
		return HttpResponseRedirect("/afcp/admin/activity/create/?%s" % urllib.urlencode(params) )
	else:
		activity.delete()
		info = "Success to cancel activity." 
		logging.info(info)
		params = { "info" : info, }
		return HttpResponseRedirect("/afcp/admin/activity/?%s" % urllib.urlencode(params) )	
		
def admin_set_current_activity(request):
	"""Set the cureent activity."""
	
	if request.method == "GET":
		activities = AFCPActivity.gql('')
		on_inscription_activity = get_on_inscription_activity()
				
		ctxt_dict = { "info"          	 : utils.get_param(request.GET, "info"),
					  "error"         	 : utils.get_param(request.GET, "error"),
					  "on_inscription_activity" : on_inscription_activity,
					  "activities"	  	 : activities,}
							  
		ctxt_dict.update(_get_common_context_dict(request))
		ctxt = Context(ctxt_dict)
		tmpl = loader.get_template("%s/admin/activity/set_current_activity.html" % Config.APP_NAME)
		return HttpResponse(tmpl.render(ctxt))
	elif request.method == "POST":
		# set current activity
		activities = AFCPActivity.gql('')
		uid = utils.get_param(request.POST, "activity_id")
		on_inscription_activity = set_on_inscription_activity(uid) 
			
		ctxt_dict = { "info"          	 : utils.get_param(request.GET, "info"),
					  "error"         	 : utils.get_param(request.GET, "error"),
					  "on_inscription_activity" : on_inscription_activity,
					  "activities"	  	 : activities,}
							  
		ctxt_dict.update(_get_common_context_dict(request))
		ctxt = Context(ctxt_dict)
		tmpl = loader.get_template("%s/admin/activity/set_current_activity.html" % Config.APP_NAME)
		return HttpResponse(tmpl.render(ctxt))	
	

	